from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from collections import Counter
from datetime import datetime
import os

app = Flask(__name__)

# 配置数据库
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data', 'mistakes.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# 定义数据模型
class Mistake(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    question = db.Column(db.Text, nullable=False)
    correct_answer = db.Column(db.String(200), nullable=False)
    user_answer = db.Column(db.String(200), nullable=False)
    knowledge_points = db.Column(db.Text)  # 存储逗号分隔的知识点
    explanation = db.Column(db.Text)
    exam_type = db.Column(db.String(100))
    date = db.Column(db.DateTime, default=datetime.utcnow)
    
    def __repr__(self):
        return f'<Mistake {self.id}>'
    
    def get_knowledge_points_list(self):
        """将知识点字符串转换为列表"""
        if self.knowledge_points:
            return [kp.strip() for kp in self.knowledge_points.split(',') if kp.strip()]
        return []

# 确保数据目录存在
os.makedirs(os.path.join(basedir, 'data'), exist_ok=True)

def init_db():
    """初始化数据库"""
    with app.app_context():
        db.create_all()

def load_mistakes():
    """加载所有错题"""
    return Mistake.query.all()

def load_knowledge():
    """从数据库加载知识点统计"""
    mistakes = load_mistakes()
    knowledge = {}
    
    for mistake in mistakes:
        kps = mistake.get_knowledge_points_list()
        for kp in kps:
            if kp not in knowledge:
                knowledge[kp] = {'count': 0, 'mistakes': []}
            knowledge[kp]['count'] += 1
            knowledge[kp]['mistakes'].append(mistake.id)
    
    return knowledge

@app.route('/')
def index():
    """首页 - 显示所有错题"""
    try:
        mistakes = load_mistakes()
        return render_template('index.html', mistakes=mistakes)
    except Exception as e:
        app.logger.error(f'Error loading mistakes: {str(e)}')
        return render_template('500.html'), 500

 # ... existing code ...
@app.route('/add_mistake', methods=['GET', 'POST'])
def add_mistake():
    """添加错题"""
    if request.method == 'POST':
        try:
            # 处理考试类型
            exam_type = request.form.get('exam_type', '')
            if exam_type == 'other':
                exam_type = request.form.get('new_exam_type', '')
            elif exam_type == '':
                exam_type = None
                
            # 创建新的错题记录
            knowledge_points_str = ', '.join([kp.strip() for kp in request.form['knowledge_points'].split(',') if kp.strip()])
            
            mistake = Mistake(
                question=request.form['question'],
                correct_answer=request.form['correct_answer'],
                user_answer=request.form['user_answer'],
                knowledge_points=knowledge_points_str,
                explanation=request.form['explanation'],
                exam_type=exam_type
            )
            
            db.session.add(mistake)
            db.session.commit()
            
            return redirect(url_for('index'))
        except Exception as e:
            app.logger.error(f'Error adding mistake: {str(e)}')
            db.session.rollback()
            return render_template('500.html'), 500
    
    # GET请求时获取已有的考试类型用于自动补全
    try:
        mistakes = load_mistakes()
        exam_types = list(set([m.exam_type for m in mistakes if m.exam_type]))
        return render_template('add_mistake.html', exam_types=exam_types)
    except Exception as e:
        app.logger.error(f'Error loading exam types: {str(e)}')
        return render_template('add_mistake.html', exam_types=[])
# ... existing code ...

@app.route('/mistake/<int:mistake_id>')
def view_mistake(mistake_id):
    """查看具体错题"""
    try:
        mistake = Mistake.query.get_or_404(mistake_id)
        return render_template('view_mistake.html', mistake=mistake)
    except Exception as e:
        app.logger.error(f'Error viewing mistake {mistake_id}: {str(e)}')
        return render_template('500.html'), 500


@app.route('/edit_mistake/<int:mistake_id>', methods=['GET', 'POST'])
def edit_mistake(mistake_id):
    """编辑错题"""
    mistake = Mistake.query.get_or_404(mistake_id)
    
    if request.method == 'POST':
        try:
            # 更新错题记录
            knowledge_points_str = ', '.join([kp.strip() for kp in request.form['knowledge_points'].split(',') if kp.strip()])
            
            mistake.question = request.form['question']
            mistake.correct_answer = request.form['correct_answer']
            mistake.user_answer = request.form['user_answer']
            mistake.knowledge_points = knowledge_points_str
            mistake.explanation = request.form['explanation']
            mistake.exam_type = request.form.get('exam_type', '')
            
            db.session.commit()
            
            return redirect(url_for('view_mistake', mistake_id=mistake.id))
        except Exception as e:
            app.logger.error(f'Error editing mistake {mistake_id}: {str(e)}')
            db.session.rollback()
            return render_template('500.html'), 500
    
    # GET请求时显示编辑表单
    try:
        mistakes = load_mistakes()
        exam_types = list(set([m.exam_type for m in mistakes if m.exam_type]))
        return render_template('edit_mistake.html', mistake=mistake, exam_types=exam_types)
    except Exception as e:
        app.logger.error(f'Error loading exam types for editing mistake {mistake_id}: {str(e)}')
        return render_template('edit_mistake.html', mistake=mistake, exam_types=[])


@app.route('/delete_mistake/<int:mistake_id>', methods=['POST'])
def delete_mistake(mistake_id):
    """删除错题"""
    try:
        mistake = Mistake.query.get_or_404(mistake_id)
        db.session.delete(mistake)
        db.session.commit()
        return redirect(url_for('index'))
    except Exception as e:
        app.logger.error(f'Error deleting mistake {mistake_id}: {str(e)}')
        db.session.rollback()
        return render_template('500.html'), 500


@app.route('/analysis')
def analysis():
    """分析页面"""
    try:
        mistakes = load_mistakes()
        knowledge = load_knowledge()
        
        # 计算统计数据
        total_mistakes = len(mistakes)
        
        # 知识点统计
        knowledge_stats = []
        for kp, data in knowledge.items():
            knowledge_stats.append({
                'name': kp,
                'count': data['count'],
                'percentage': round((data['count'] / total_mistakes) * 100, 2) if total_mistakes > 0 else 0
            })
        
        # 按数量排序
        knowledge_stats.sort(key=lambda x: x['count'], reverse=True)
        
        # 考试类型统计
        exam_types = [mistake.exam_type for mistake in mistakes if mistake.exam_type]
        exam_type_stats = dict(Counter(exam_types)) if exam_types else {}
        
        return render_template('analysis.html', 
                             total_mistakes=total_mistakes,
                             knowledge_stats=knowledge_stats if knowledge_stats else [],
                             exam_type_stats=exam_type_stats if exam_type_stats else {})
    except Exception as e:
        app.logger.error(f'Error in analysis: {str(e)}')
        return render_template('500.html'), 500

@app.route('/knowledge')
def knowledge_points():
    """知识点页面"""
    try:
        knowledge = load_knowledge()
        knowledge_list = []
        for kp, data in knowledge.items():
            knowledge_list.append({
                'name': kp,
                'count': data['count'],
                'mistake_ids': data['mistakes']
            })
        
        # 加载错题以显示相关问题
        mistakes = load_mistakes()
        mistake_dict = {m.id: m for m in mistakes}
        
        return render_template('knowledge.html', 
                             knowledge_list=knowledge_list if knowledge_list else [],
                             mistakes=mistake_dict if mistake_dict else {})
    except Exception as e:
        app.logger.error(f'Error in knowledge points: {str(e)}')
        return render_template('500.html'), 500

# 添加错误处理程序
@app.errorhandler(404)
def not_found_error(error):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    db.session.rollback()
    return render_template('500.html'), 500

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)